<?php
/**
 * Logger class
 * 
 * @author Alan Moreau - moreau.alan@gmail.com
 *
 */
class Mac_Logger
{
    const LEVEL_DEBUG = 'DEBUG';
    const LEVEL_INFO = 'INFO';
    const LEVEL_WARNING = 'WARNING';
    const LEVEL_ERROR = 'ERROR';

    private $logPath;
    private $jobId;
    private $jobDesc;
    private $scriptInfo;
    private $logFilename;
    private $logLifetime;
    private $handleFile;

    private static $instance;
    
    public static function getLogger ()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }
    
    public function debug ($mess)
    {
        $this->log(self::LEVEL_DEBUG, $mess);
    }

    public function info ($mess)
    {
        $this->log(self::LEVEL_INFO, $mess);
    }

    public function warning ($mess)
    {
        $this->log(self::LEVEL_WARNING, $mess);
    }

    public function error ($mess)
    {
        $this->log(self::LEVEL_ERROR, $mess);
    }

    /**
     * Initialize loggger and create output file
     *
     */
    private function __construct ()
    {
        if (!file_exists(LOG_PATH))
            die('Log path invalide : '.LOG_PATH);

        $today = date('Ymd');
        $this->logFilename = date('Y-m-d').'.log';

                
        // check if the file is already exists, otherwise we create it
        if (!file_exists(LOG_PATH . '/' . $this->logFilename)) {
            //write start markup
            $paramsStart = array(
                'date'      => $today,
                'encoding'  => 'UTF-8',
            );
            
            $content  = $this->generateLine('START', $paramsStart);
            
            // create file if not exists and place pointer at the end
            $this->handleFile = fopen(LOG_PATH . '/' . $this->logFilename, 'a');
            if ($this->handleFile === false || is_null($this->handleFile)){
                die('Impossible de créer le fichier de log (#1)');
            }
        
            if (fwrite($this->handleFile, $content) === false){
                die('Impossible de créer le fichier de log (#2)');
            }
        } else {
            // create file if not exists and place pointer at the end
            $this->handleFile = fopen(LOG_PATH . '/' . $this->logFilename, 'a');
            if ($this->handleFile === false || is_null($this->handleFile)){
                die('Impossible de créer le fichier de log (#1)');
            }
        }
    }
    
    /**
     * Call when GC free this object
     */
    public function __destruct ()
    {
        if ($this->handleFile){
            fclose($this->handleFile);
        }
    }

    /**
     * Write a log message in the file
     *
     * @param string $level message level
     * @param string $msg log message
     */
    public function log ($level, $msg = '')
    {
        if (fwrite($this->handleFile, $this->generateLine($level, $msg)) === false){
            die('Impossible d\'ecrire dans le fichier de log (#3)');
        }
    }


    /**
     * Generate a log line
     *
     * @param string $level message level
     * @param string|array $params log parameters (array) or log message
     * @return string the log line
     */
    private function generateLine ($level, $params)
    {
        $line = date('Ymd-His') . ' @' . $level;
        
        if (isset($_SERVER) && isset($_SERVER['REMOTE_ADDR'])
            && in_array($level, array('INFO', 'WARNING', 'ERROR')))
             $line .=  ' ' . $_SERVER['REMOTE_ADDR'] . ':';
        
        if (is_array($params))
        {
            foreach ($params as $name => $value)
            {
                if (is_array($value))
                    $value = var_export($value, true);

                $value = trim($value);
                $value = preg_replace('/\n/', ' \n ', $value);
                $value = preg_replace('/"/', '*', $value);
                $line .= ' ' . mb_strtoupper($name) . '="' . $value . '"';
            }
        }
        else if (trim($params) != '')
        {
            $params = trim($params);
            $params = preg_replace('/\n/', ' \n ', $params);
            $line .= ' ' . $params;
        }

        return $line . "\n";
    }
}